package com.mto.module.karaoke.portlet;

import java.io.IOException;
import java.io.InputStream;
import java.io.StringWriter;
import java.io.UnsupportedEncodingException;
import java.text.DateFormat;
import java.text.DecimalFormat;
import java.util.Date;
import java.util.List;

import javax.portlet.ActionRequest;
import javax.portlet.ActionResponse;
import javax.portlet.PortletException;
import javax.portlet.PortletRequest;
import javax.portlet.RenderRequest;
import javax.portlet.RenderResponse;
import javax.portlet.ResourceRequest;
import javax.portlet.ResourceResponse;

import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringUtils;

import com.liferay.counter.service.CounterLocalServiceUtil;
import com.liferay.portal.kernel.exception.PortalException;
import com.liferay.portal.kernel.exception.SystemException;
import com.liferay.portal.kernel.log.Log;
import com.liferay.portal.kernel.log.LogFactoryUtil;
import com.liferay.portal.kernel.portlet.LiferayPortletConfig;
import com.liferay.portal.kernel.repository.model.FileEntry;
import com.liferay.portal.kernel.repository.model.Folder;
import com.liferay.portal.kernel.servlet.SessionErrors;
import com.liferay.portal.kernel.servlet.SessionMessages;
import com.liferay.portal.kernel.upload.UploadPortletRequest;
import com.liferay.portal.kernel.util.DateFormatFactoryUtil;
import com.liferay.portal.kernel.util.HttpUtil;
import com.liferay.portal.kernel.util.MimeTypesUtil;
import com.liferay.portal.kernel.util.ParamUtil;
import com.liferay.portal.kernel.util.StringPool;
import com.liferay.portal.kernel.util.WebKeys;
import com.liferay.portal.kernel.xml.Attribute;
import com.liferay.portal.kernel.xml.Document;
import com.liferay.portal.kernel.xml.DocumentException;
import com.liferay.portal.kernel.xml.Element;
import com.liferay.portal.kernel.xml.SAXReaderUtil;
import com.liferay.portal.service.ServiceContext;
import com.liferay.portal.service.ServiceContextFactory;
import com.liferay.portal.theme.ThemeDisplay;
import com.liferay.portal.util.PortalUtil;
import com.liferay.portlet.documentlibrary.model.DLFileShortcut;
import com.liferay.portlet.documentlibrary.service.DLAppLocalServiceUtil;
import com.liferay.portlet.documentlibrary.service.DLAppServiceUtil;
import com.liferay.util.bridges.mvc.MVCPortlet;
import com.mto.module.karaoke.model.Category;
import com.mto.module.karaoke.model.Song;
import com.mto.module.karaoke.model.UserSongs;
import com.mto.module.karaoke.service.CategoryLocalServiceUtil;
import com.mto.module.karaoke.service.SongLocalServiceUtil;
import com.mto.module.karaoke.service.SongServiceUtil;
import com.mto.module.karaoke.service.UserSongsLocalServiceUtil;

public class KaraokePortlet extends MVCPortlet {

	private static final Log LOG = LogFactoryUtil.getLog(KaraokePortlet.class);
	private static final String LYRIC_FOLDER = "Karaoke_Lyric";
	private static final String BEAT_FOLDER = "BEAT_FOLDER";
	private static final String X_FOLDER = "BEAT_FOLDER";
	// private static Folder lyricFolder = null;
	private static Folder karaokeFolder = null;

	public void updateSong(ActionRequest actionRequest,
			ActionResponse actionResponse) throws IOException,
			PortletException, PortalException, SystemException {

		SessionMessages
				.add(actionRequest,
						((LiferayPortletConfig) getPortletConfig())
								.getPortletName()
								+ SessionMessages.KEY_SUFFIX_HIDE_DEFAULT_ERROR_MESSAGE);

		LOG.debug("================= createSong =================");

		UploadPortletRequest request = PortalUtil
				.getUploadPortletRequest(actionRequest);

		long songId = ParamUtil.getLong(request, "songId");
		String songName = ParamUtil.getString(request, "songName");
		String songAuthor = ParamUtil.getString(request, "songAuthor");
		Integer songCategory = ParamUtil.getInteger(request, "songCategory");
		String songSinger = ParamUtil.getString(request, "songSinger");
		String fileName = request.getFileName("file");
		long fileSize = request.getSize("file");

		String audioFileName = request.getFileName("audio");
		long audioFileSize = request.getSize("audio");

		LOG.debug("songName: " + songName);
		LOG.debug("songAuthor: " + songAuthor);
		LOG.debug("songCategory: " + songCategory);
		LOG.debug("songSinger: " + songSinger);
		LOG.debug("fileName: " + fileName);
		LOG.debug("fileSize: " + fileSize);
		LOG.debug("audioFileName: " + audioFileName);
		LOG.debug("audioFileSize: " + audioFileSize);

		/** validate inputs **/
		boolean hasErrors = false;
		if (StringUtils.isBlank(songName)) {
			hasErrors = true;
			SessionErrors.add(actionRequest, "songName-required");
		}
		if (StringUtils.isBlank(songAuthor)) {
			hasErrors = true;
			SessionErrors.add(actionRequest, "songAuthor-required");
		}
		if (songCategory == null || songCategory <= 0) {
			hasErrors = true;
			SessionErrors.add(actionRequest, "songCategory-required");
		}

		if (!hasErrors) {
			Song song = null;
			Date now = new Date();
			if (songId > 0) {
				song = SongLocalServiceUtil.getSong(songId);
				song.setModifiedDate(now);
			} else {
				songId = CounterLocalServiceUtil
						.increment(Song.class.getName());
				song = SongLocalServiceUtil.createSong(songId);
				song.setCreateDate(now);
				song.setModifiedDate(now);
			}
			song.setSongAuthor(songAuthor);
			song.setSongCategory(songCategory);
			song.setSongName(songName);
			song.setSongSinger(songSinger);

			// /** upload file **/
			// if(fileSize > 0) {
			// ThemeDisplay themeDisplay = (ThemeDisplay)
			// actionRequest.getAttribute(WebKeys.THEME_DISPLAY);
			// ServiceContext serviceContext =
			// ServiceContextFactory.getInstance(actionRequest);
			// String contentType = request.getContentType("file");
			// InputStream inputStream = request.getFileAsStream("file");
			// Folder folder = getLyricfolder(actionRequest);
			// long folderId = folder.getFolderId();
			// long repositoryId = folder.getRepositoryId();
			// FileEntry fileEntry = DLAppLocalServiceUtil.addFileEntry(
			// themeDisplay.getUserId(),
			// repositoryId,
			// folderId,
			// fileName,
			// contentType,
			// fileName,
			// StringPool.BLANK,
			// DateFormatFactoryUtil.getSimpleDateFormat("dd/MM/yyyy HH.mm.ss",
			// themeDisplay.getTimeZone()).format(new Date()),
			// inputStream,
			// fileSize,
			// serviceContext);
			// String fileUrl =
			// themeDisplay.getPortalURL()+"/c/document_library/get_file?uuid="+fileEntry.getUuid()+"&groupId="+themeDisplay.getScopeGroupId()
			// ;
			// LOG.debug("fileUrl: " + fileUrl);
			// song.setSongUrl(fileUrl);
			// }

			/** upload file lyric **/
			// if(fileSize > 0) {

			/* upload lyric file */
			String lyricUrl = uploadKaraokeResource(actionRequest, request,
					LYRIC_FOLDER, "file");
			LOG.debug("file lyric Url: " + lyricUrl);
			song.setSongUrl(lyricUrl);

			/* upload audio file */
			String audioUrl = uploadKaraokeResource(actionRequest, request,
					BEAT_FOLDER, "audio");
			LOG.debug("file audio Url: " + audioUrl);
			song.setAudioUrl(audioUrl);

			// }

			SongLocalServiceUtil.updateSong(song);

			String redirectUrl = ParamUtil.getString(request, "redirectUrl");
			redirectUrl = HttpUtil.setParameter(redirectUrl,
					actionResponse.getNamespace() + "songId", songId);
			LOG.debug("redirectUrl: " + redirectUrl);
			actionResponse.sendRedirect(redirectUrl);
		} else {
			actionResponse.setRenderParameter("jspPage",
					"/jsps/quan-tri/update.jsp");
		}
	}

	public void updateCategory(ActionRequest actionRequest,
			ActionResponse actionResponse) throws IOException,
			PortletException, PortalException, SystemException {
		long categoryId = ParamUtil.getLong(actionRequest, "categoryId");
		String name = ParamUtil.getString(actionRequest, "name");
		if (StringUtils.isBlank(name)) {
			SessionErrors.add(actionRequest, "name-required");
			actionResponse.setRenderParameter("jspPage", "/jsps/quan-tri/category/update.jsp");
			return;
		}
		Category category;
		if(categoryId > 0) {
			category = CategoryLocalServiceUtil.getCategory(categoryId);
		} else {
			categoryId = CounterLocalServiceUtil.increment(Category.class.getName());
			category = CategoryLocalServiceUtil.createCategory(categoryId); 
		}
		category.setName(name);
		CategoryLocalServiceUtil.addCategory(category);
		String redirectUrl = ParamUtil.getString(actionRequest, "redirectUrl");
		redirectUrl = HttpUtil.setParameter(redirectUrl, actionResponse.getNamespace() + "categoryId", categoryId);
		actionResponse.sendRedirect(redirectUrl);
	}
	
	private String uploadKaraokeResource(ActionRequest actionRequest,
			UploadPortletRequest request, String folderType, String resouceType)
			throws PortalException, SystemException, IOException {

		System.out.println("[folderType: " + folderType + "] "
				+ "[resouceType: " + resouceType + "]");
		ThemeDisplay themeDisplay = (ThemeDisplay) actionRequest
				.getAttribute(WebKeys.THEME_DISPLAY);
		ServiceContext serviceContext = ServiceContextFactory
				.getInstance(actionRequest);
		String contentType = request.getContentType(resouceType);
		InputStream inputStream = request.getFileAsStream(resouceType);
		InputStream newIn = null;
		String fileName = request.getFileName(resouceType);
		System.out.println("fileName: " + fileName);
		long fileSize = request.getSize(resouceType);

		if ("file".equals(resouceType)) {
			String lyricSong = parserStream(inputStream);
			return lyricSong;
		} else {
			newIn = inputStream;
		}

		// // copy inputstreams

		Folder folder = getLyricfolder(actionRequest, folderType);
		long folderId = folder.getFolderId();
		long repositoryId = folder.getRepositoryId();
		FileEntry fileEntry = DLAppLocalServiceUtil.addFileEntry(
				themeDisplay.getUserId(),
				repositoryId,
				folderId,
				fileName,
				contentType,
				fileName,
				StringPool.BLANK,
				DateFormatFactoryUtil.getSimpleDateFormat(
						"dd/MM/yyyy HH.mm.ss", themeDisplay.getTimeZone())
						.format(new Date()), newIn, fileSize, serviceContext);
		String lyricUrl = themeDisplay.getPortalURL()
				+ "/c/document_library/get_file?uuid=" + fileEntry.getUuid()
				+ "&groupId=" + themeDisplay.getScopeGroupId();

		return lyricUrl;
	}

	// private Folder getRootFolder(PortletRequest request, String name)
	// throws PortalException, SystemException {
	// ThemeDisplay themeDisplay = (ThemeDisplay) request
	// .getAttribute(WebKeys.THEME_DISPLAY);
	// long repositoryId = themeDisplay.getScopeGroupId();
	// Folder folder = null;
	// try {
	// folder = DLAppServiceUtil.getFolder(repositoryId, 0, name);
	// } catch (Exception e) {
	// LOG.warn("No folder exists with the name " + name +
	// ". Creating new one...");
	// }
	// if (folder == null) {
	// ServiceContext serviceContext =
	// ServiceContextFactory.getInstance(DLFileShortcut.class.getName(),
	// request);
	// folder = DLAppServiceUtil.addFolder(repositoryId, 0l, name,
	// StringPool.BLANK, serviceContext);
	// }
	// return folder;
	// }

	/**
	 * parser xml form thanh krl format cua rice karaoke
	 * 
	 * @param inputStream
	 * @return
	 */
	private String parserStream(InputStream inputStream) {

		// InputStream in = null;
		try {

			StringWriter writer = new StringWriter();
			IOUtils.copy(inputStream, writer, "UTF-8");
			String xmldata = writer.toString();
			Document doc = SAXReaderUtil.read(xmldata);

			Element root = doc.getRootElement();
			List<Element> params = root.elements();

			StringBuffer buffer = new StringBuffer();
			buffer.append("[");

			int index = 0;
			int begin_end = 0;

			for (Element param : params) {
				buffer.append("[");

				List<Element> is = param.elements();
				// start
				Element start = is.get(0);
				Attribute startVa = start.attribute("va");
				int startTime = gettime(startVa.getText()) -250;
				if (begin_end <= 0) {
					begin_end = startTime;
					buffer.append(f_format((float) startTime / 1000));
				} else {
					buffer.append(f_format((float) begin_end / 1000));
				}
				buffer.append(",");
				// end
				Element end = is.get(is.size() - 1);
				Attribute endVa = end.attribute("va");
				int endTime = gettime(endVa.getText());
				buffer.append(f_format((float) endTime / 1000));
				buffer.append(",");

				// line
				buffer.append("[");
				int timeOrder = 0;
				for (Element i : is) {
					buffer.append("[");
					// text
					Attribute va = i.attribute("va");
					int time = gettime(va.getText());			
					buffer.append(f_format((float) ((time - begin_end) - 250) / 1000));

					buffer.append(",");
					// text
					buffer.append("\"");
					buffer.append(i.getText());
					buffer.append("\"");

					buffer.append(",");
					buffer.append(f_format((float) (time - begin_end) / 1000));
					
					// time
					buffer.append("]");
					if (timeOrder != is.size() - 1) {
						buffer.append(",");
					}
					timeOrder++;
				}

				buffer.append("],");
				// reder option
				buffer.append("{}");
				buffer.append("]");
				if (index != params.size() - 1) {
					buffer.append(",");
				}
				index++;
				begin_end = endTime;
			}

			buffer.append("]");
			return buffer.toString();
			// in = new
			// ByteArrayInputStream(buffer.toString().getBytes("UTF-8"));
		} catch (UnsupportedEncodingException e) {
//			LOG.error(e);
		} catch (IOException e) {
//			LOG.error(e);
		} catch (DocumentException e) {
//			LOG.error(e);
		}
		
		return "";
	}

	private String f_format(float f){
		float temp= f;
		DecimalFormat df = new DecimalFormat("#.###");
		return df.format(temp);
	}
	
	
	private int gettime(String text) {
		String[] parts = text.split(":");
		int minutes = Integer.valueOf(parts[0]);
		int seconds = Integer.valueOf(parts[1]);
		int miliseconds = Integer.valueOf(parts[2]);
		int time = (minutes * 60 + seconds) * 1000 + miliseconds;
		return time;
	}

	private Folder getRootFolder(PortletRequest request, String name)
			throws PortalException, SystemException {
		ThemeDisplay themeDisplay = (ThemeDisplay) request
				.getAttribute(WebKeys.THEME_DISPLAY);
		long repositoryId = themeDisplay.getScopeGroupId();
		Folder folder = null;
		try {
			folder = DLAppServiceUtil.getFolder(repositoryId, 0, name);
		} catch (Exception e) {
			LOG.warn("No folder exists with the name " + name
					+ ". Creating new one...");
		}
		if (folder == null) {
			ServiceContext serviceContext = ServiceContextFactory.getInstance(
					DLFileShortcut.class.getName(), request);
			folder = DLAppServiceUtil.addFolder(repositoryId, 0l, name,
					StringPool.BLANK, serviceContext);
		}
		return folder;
	}

	public Folder getLyricfolder(PortletRequest request, String folder)
			throws PortalException, SystemException {
		if (karaokeFolder == null) {
			karaokeFolder = getRootFolder(request, folder);
		}
		return karaokeFolder;
	}

	public void deleteSong(ActionRequest actionRequest,
			ActionResponse actionResponse) throws IOException,
			PortletException, PortalException, SystemException {
		long songId = ParamUtil.getLong(actionRequest, "songId");
		Song song = SongServiceUtil.getSong(songId);
		SongLocalServiceUtil.deleteSong(song);
		actionResponse.sendRedirect(ParamUtil.getString(actionRequest,
				"redirectUrl"));
	}

	@Override
	public void doView(RenderRequest renderRequest,
			RenderResponse renderResponse) throws IOException, PortletException {
		LOG.debug("############ doView");
		super.doView(renderRequest, renderResponse);
	}

	@Override
	public void doEdit(RenderRequest renderRequest,
			RenderResponse renderResponse) throws IOException, PortletException {
		LOG.debug("############ doEdit");
		super.doEdit(renderRequest, renderResponse);
	}

	public void saveKaraoke(ActionRequest request, ActionResponse response) throws IOException, PortletException, PortalException, SystemException {
		
		long songId = ParamUtil.getLong(request, "songId");
		String audioUrl = ParamUtil.getString(request, "audioUrl");
		String description = ParamUtil.getString(request, "description");
		boolean isShow = ParamUtil.getBoolean(request, "isShow");
		String avatar = ParamUtil.getString(request, "avatar");
		
		if(avatar==null || avatar.isEmpty()){
			avatar="http://image.star.zing.vn//images/avatars/default/img06.jpg";
		}
		
		Date now = new Date();
		
		long userSongId = CounterLocalServiceUtil.increment(UserSongs.class.getName());
		UserSongs userSongs = UserSongsLocalServiceUtil.createUserSongs(userSongId );
		userSongs.setSongId(songId);
		userSongs.setAvatar(avatar);
		userSongs.setDescription(description);
		userSongs.setIsShow(isShow);
		userSongs.setRecodingUrl(audioUrl);
		userSongs.setCreateDate(now);
		ThemeDisplay themeDisplay = (ThemeDisplay) request.getAttribute(WebKeys.THEME_DISPLAY);
		userSongs.setUserId(themeDisplay.getUserId());
	
		UserSongsLocalServiceUtil.createUserSongs(userSongs);
		request.getPortletSession().removeAttribute("audioUrl");
		
		String redirectUrl = ParamUtil.getString(request, "redirectUrl");
		response.sendRedirect(redirectUrl);
	}

	@Override
	public void serveResource(ResourceRequest resourceRequest,
			ResourceResponse resourceResponse) throws IOException,
			PortletException {
		ThemeDisplay themeDisplay = (ThemeDisplay) resourceRequest
				.getAttribute(WebKeys.THEME_DISPLAY);
		
		DateFormat dateFormat = DateFormatFactoryUtil.getSimpleDateFormat("ddMMyyhhmmss", themeDisplay.getTimeZone());
		String pattern = dateFormat.format(new Date());
		try {
			UploadPortletRequest uploadRequest = PortalUtil
					.getUploadPortletRequest(resourceRequest);
		
			String fileName = pattern + /*ParamUtil.getString(uploadRequest, "fname", "") + "-" +*/ themeDisplay.getUserId() + ".mp3";
			ServiceContext serviceContext = ServiceContextFactory.getInstance(resourceRequest);
			InputStream inputStream = uploadRequest.getFileAsStream("data");
			Folder folder = getRootFolder(resourceRequest, "WAVs");
			long folderId = folder.getFolderId();
			long repositoryId = folder.getRepositoryId();
			long fileSize = uploadRequest.getSize("data");
	
			System.out.println("fileSize: " + fileSize);
			System.out.println("fileName: " + fileName);
			
			FileEntry fileEntry = DLAppLocalServiceUtil.addFileEntry(
					themeDisplay.getUserId(),
					repositoryId,
					folderId,
					fileName,
					MimeTypesUtil.getContentType(fileName),
					fileName,
					StringPool.BLANK,
					DateFormatFactoryUtil.getSimpleDateFormat(
							"dd/MM/yyyy HH.mm.ss", themeDisplay.getTimeZone())
							.format(new Date()), inputStream, fileSize,
					serviceContext);
	
			String fileUrl = themeDisplay.getPortalURL()
					+ "/c/document_library/get_file?uuid=" + fileEntry.getUuid()
					+ "&groupId=" + themeDisplay.getScopeGroupId();
			System.out.println(fileUrl);
			resourceRequest.getPortletSession().setAttribute("audioUrl", fileUrl);
			resourceResponse.getWriter().write("{audioUrl:\"" + fileUrl + "\"}");
		} catch(Exception exception) {
			
		}
	}
}
